﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<link rel="Stylesheet" type="text/css" media="screen" href="Screen.css" />
  <title>StpCallback_TransmitGetBuffer</title>
</head>
<body>
	<h3>StpCallback_TransmitGetBuffer</h3>
	<hr />
<pre>
void* StpCallback_TransmitGetBuffer
(
    BRIDGE*       bridge,
    unsigned int  portIndex,
    unsigned int  bpduSize
);
</pre>
	<h4>
		Summary</h4>
	<p>
		Used together with <a href="StpCallback_TransmitReleaseBuffer.html">
		StpCallback_TransmitReleaseBuffer</a> to transmit a BPDU generated by the STP library.</p>
	<h4>
		Parameters</h4>
	<dl>
		<dt>bridge</dt>
		<dd>The application receives in this parameter a pointer to the bridge object returned by
			<a href="STP_CreateBridge.html">STP_CreateBridge</a>.</dd>
		<dt>portIndex</dt>
		<dd>The application receives in this parameter the zero-based index of the port to which the 
			BPDU is to be sent.</dd>
		<dt>bpduSize</dt>
		<dd>The size of the BPDU packet, excluding non-STP headers. See the Remarks section for more 
			information.</dd>
	</dl>
	<h4>Return Value</h4>
		<p>The application must return either:</p>
	<ul>
		<li>a pointer to a buffer where the STP library will construct the BPDU to be sent, or</li>
		<li>NULL, if the application wants to discard the BPDU.</li>
	</ul>
	<p>The application might want to discard a BPDU, for instance, when it knows that a port is hardwired to a non-STP device and wants to save bandwidth by 
		not sending BPDUs to that port.</p>
	<h4>
		Remarks</h4>
		<p>
			This callback, together with <a href="StpCallback_TransmitReleaseBuffer.html">
		StpCallback_TransmitReleaseBuffer</a>, are used for transmitting BPDUs generated by the 
			STP library. They are designed this way (GetBuffer/ReleaseBuffer) to allow the STP library 
			to work with zero-copy Ethernet drivers. Such Ethernet drivers have similar 
			GetBuffer/ReleaseBuffer routines, and these routines allow the software to construct 
			Ethernet packets directly in the DMA memory of the Ethernet controller (hence the name 
			&quot;zero-copy&quot;).</p>
	<p>
			If a zero-copy Ethernet driver is not available, then this callback can return a pointer 
			to a RAM-based buffer whose length is greater than or equal to <code>bpduSize</code>.
		This buffer can be, for instance, a static C variable of type &quot;byte array&quot;. Note that the STP 
			library, at least in MSTP mode, sends BPDUs with greatly varying sizes, so heap allocation should generally be 
			avoided, or else the heap might become badly fragmented.</p>
	<p>
			An embedded application will usually have to prepend non-STP headers to the BPDU, and 
			these headers usually have a length of 21 bytes. So unless the Eternet driver prepends 
			some of these headers itself, this function should allocate a buffer whose length is <code>bpduSize+21</code>, construct the non-STP headers in the first 21 bytes, and return the address of the 22nd byte of this buffer 
			(e.g., <code>&buffer[21]</code>). </p>
	<p>
			The non-STP headers usually have the following format:</p>
	<ul>
		<li>6 bytes for the destination MAC address, which for BPDU packets is always 01-80-C2-00-00-00.</li>
		<li>6 bytes for the source MAC address, which is the same MAC address the application has 
			specified in the last call to <a href="STP_CreateBridge.html">STP_CreateBridge</a> or
			<a href="STP_SetBridgeAddress.html">STP_SetBridgeAddress</a>.</li>
		<li>4 bytes for the VLAN tag. For STP and RSTP bridges (no VLANs), these bytes can be 0x81, 0x00, 0x00, 0x00. On certain switch 
			ICs, such as IP175C, this callback must write the destination port number (the <code>portIndex</code>
			parameter) in the second byte of this field.</li>
		<li>2 bytes for frame size, so the length of non-STP headers (in this example equal to 21) plus 
			<code>bpduSize</code>. This field must be written in network byte order (MS byte, then LS byte).</li>
		<li>3 bytes for the LLC field, which normally are 0x42, 0x42, 0x03.</li>
	</ul>

	<p>
			The largest <code>bpduSize</code> that the STP library can request is as follows:</p>
	<ul>
		<li>For 802.1w-2001: 35 bytes (§9.3 in the 802.1w-2001 standard).</li>
		<li>For 802.1D-2004: 36 bytes. (§9.3.3 in the 802.1D-2004 standard).</li>
		<li>For 801.1Q-2005: <code>103 + 16 * numberOfTrees</code>, so up to 1126 bytes for 64 trees (§14.6 in 
			the 802.1Q-2011 standard).</li>
	</ul>
	<p>
		If this callback returns an address other than NULL, the STP library will construct 
		a BPDU at the returned address and will call
		<a href="StpCallback_TransmitReleaseBuffer.html">StpCallback_TransmitReleaseBuffer</a> 
		afterwards.</p>
	<p>
		If this callback returns NULL, the STP library 
		won&#39;t write its BPDU and won&#39;t call <a href="StpCallback_TransmitReleaseBuffer.html">StpCallback_TransmitReleaseBuffer</a> 
		afterwards.</p>
	<p>
		Losing of too many BPDUs in a network can cause Ethernet loops to be formed, resulting in 
		immediate flooding of that network. For this reason, it is recommended that BPDUs are sent 
		via some high-priority channel of the Ethernet driver; if the Ethernet driver does not 
		know about priorities, it is recommended that this function waits in case Ethernet 
		transmission is currently unavailable (due to full TX buffers, for example).</p>

</body>
</html>
